package io.nads.api.impl;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import io.nads.api.FileUploader;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

/**
 * 上传文件返回url
 */
@Data
@Slf4j
public class QiniuUploader implements FileUploader {
    private final String accessKey;
    private final String secretKey;
    private final String bucketName;
    private final String domain; // 七牛云存储空间绑定的域名
    private final long expireInSeconds; // 私有下载URL过期时间
    private Auth auth;
    private UploadManager uploadManager;

    public QiniuUploader(String accessKey, String secretKey, String bucketName, String domain, long expireInSeconds) {
        this.accessKey = accessKey;
        this.secretKey = secretKey;
        this.bucketName = bucketName;
        this.domain = domain;
        this.expireInSeconds = expireInSeconds;
        this.auth = Auth.create(accessKey, secretKey);

        // 创建uploader
        Configuration cfg = Configuration.create(Region.autoRegion());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2; // 指定分片上传版本
        this.uploadManager = new UploadManager(cfg);

        log.info("QiniuUploader初始化成功, bucketName={}, domain={}, expireInSeconds={}", bucketName, domain, expireInSeconds);
    }

    @Override
    public String upload(MultipartFile file) {
        try {
            InputStream fileInputStream = file.getInputStream();
            String originalFilename = file.getOriginalFilename();

            // 调用InputStream版本的upload方法
            return upload(fileInputStream, originalFilename);

        } catch (IOException e) {
            log.error("获取文件输入流失败", e);
            return "";
        }
    }
    
    /**
     * 上传InputStream到七牛云
     * @param inputStream 输入流
     * @param filename 文件名（用于生成key和确定文件类型）
     * @return 上传结果URL或key
     */
    public String upload(InputStream inputStream, String filename) {
        String upToken = auth.uploadToken(bucketName);
        try {
            // 生成包含文件后缀的key
            String key = generateKeyWithExtension(filename);
            
            Response response = this.uploadManager.put(inputStream, key, upToken, null, null);
            // 解析上传成功的结果
            JSONObject json = JSONUtil.parseObj(response.body());
            DefaultPutRet putRet = json.toBean(DefaultPutRet.class);
            log.info("InputStream上传成功 {}, key = {}, hash = {}", putRet, putRet.key, putRet.hash);

            String url = getPrivateDownloadUrl(putRet.key, expireInSeconds);
            log.info("下载的url = {}", url);
            return url;

        } catch (IOException e) {
            log.error("InputStream上传失败", e);
            return "";
        }
    }
    
    /**
     * 生成包含文件后缀的key
     * @param originalFilename 原始文件名
     * @return 生成的key
     */
    private String generateKeyWithExtension(String originalFilename) {
        // 生成UUID作为文件名前缀
        String uuid = java.util.UUID.randomUUID().toString().replace("-", "");
        
        // 提取文件后缀
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        
        return uuid + extension;
    }
    
    /**
     * 构建文件的可访问URL
     * @param key 文件的key
     * @return 完整的访问URL
     */
    private String buildAccessUrl(String key) {
        if (domain == null || domain.trim().isEmpty()) {
            throw new IllegalStateException("Domain未配置，无法生成访问URL");
        }
        
        // 确保domain以http://或https://开头
        String normalizedDomain = domain;
        if (!domain.startsWith("http://") && !domain.startsWith("https://")) {
            normalizedDomain = "https://" + domain;
        }
        
        // 确保domain不以/结尾
        if (normalizedDomain.endsWith("/")) {
            normalizedDomain = normalizedDomain.substring(0, normalizedDomain.length() - 1);
        }
        
        // 注意：七牛云私有空间需要下载凭证，这里返回的是基础URL
        // 如果是私有空间，需要使用Auth.privateDownloadUrl()方法生成带签名的URL
        return normalizedDomain + "/" + key;
    }
    
    /**
     * 生成私有空间的下载URL（带签名）
     * @param key 文件的key
     * @param expireInSeconds 过期时间（秒）
     * @return 带签名的下载URL
     */
    public String getPrivateDownloadUrl(String key, long expireInSeconds) {
        if (domain == null || domain.trim().isEmpty()) {
            throw new IllegalStateException("Domain未配置，无法生成访问URL");
        }
        
        String baseUrl = buildAccessUrl(key);
        return auth.privateDownloadUrl(baseUrl, expireInSeconds);
    }
}